package corp.edu.amadeus.core.bluetooth.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.log4j.Logger;
import corp.edu.amadeus.core.bluetooth.service.ifc.IBluetoothService;
import corp.edu.amadeus.core.schedule.inquiry.InquiryTask;
import corp.edu.amadeus.core.schedule.sender.broadcast.BroadcastSenderTask;
import corp.edu.amadeus.utils.Constants;
import corp.edu.amadeus.utils.file.FileUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import corp.edu.amadeus.utils.file.ResourceFinder;
import java.util.Properties;

public class BluetoothService implements IBluetoothService {

	public static String BROADCASTER_MODE = "broadcast";
	public static String TICKER_MODE = "ticker";

	private static Logger log = Logger.getLogger(BluetoothService.class);
	private Timer issuer = null;
	private boolean issuer_enabled = false;
	private Timer inquirer = null;
	private boolean inquirer_enabled = false;
	private String content_name = "";
	private boolean hasContent = false;
	private String mode = "";
	private File config_file;
	private Map<String, String> modes = null;

	/**
	 * By default the issuer frequency is each 10 minutes.
	 */
	private int issuerFrequency = 10;
	/**
	 * By default the inquiry frequency is each 5 minutes.
	 */
	private int inquirerFrequency = 5;

	public BluetoothService() throws Exception {
		this.init();
	}

	public void setSendContent(byte[] content, String filename)
		throws Exception {
		this.content_name = filename;
		FileUtils.eraseFiles(Constants.CONTENT_FOLDER);
		String file_path = Constants.CONTENT_FOLDER + File.separator +
			filename;
		File content_file = new File(file_path);
		FileOutputStream fos = new FileOutputStream(content_file);
		FileUtils.binaryTransferm(fos, content);
		this.hasContent = true;
	}

	/**
	 *
	 */
	public void setInquirerFrequency(int f) {
		this.inquirerFrequency = f;
	}


	/**
	 *
	 */
	public int getInquirerFrequency() {
		return this.inquirerFrequency;
	}


	/**
	 *
	 */
	public void enableInquiry() {
		if(this.inquirer_enabled ) {
			this.disableInquiry();
		}
		this.inquirer = new Timer();
		this.inquirer.schedule(new InquiryTask(),
				this.inquirerFrequency * 60 * 1000,
				this.inquirerFrequency * 60 * 1000);
		this.inquirer_enabled = true;
	}

	public void disableInquiry() {
		if(this.inquirer != null) {
			this.inquirer.purge();
			this.inquirer.cancel();
		}
		this.inquirer_enabled = false;
		this.inquirer = null;
	}

	public void setIssuerFrequency(int minutes) {
		this.issuerFrequency = minutes;
	}

	public int getIssuerFrequency() {
		return this.issuerFrequency;
	}

	public void enableIssuer()  throws Exception {
		if(!this.hasContent) {
			throw new Exception("No se ha definido ningun contenido para enviar.");
		}
		if(this.issuer_enabled) {
			this.disableIssuer();
		}
		this.issuer = new Timer();
		this.issuer.schedule(new BroadcastSenderTask(
				Constants.CONTENT_FOLDER,this.content_name),
			this.issuerFrequency * 60 * 1000,
			this.issuerFrequency * 60 * 1000);
		this.issuer_enabled = true;
	}

	public boolean isIssuerEnabled() {
		return this.issuer_enabled;
	}

	public boolean isInquiring() {
		return this.inquirer_enabled;
	}

	public void disableIssuer() {
		if(this.issuer != null) {
			this.issuer.purge();
			this.issuer.cancel();
		}
		this.issuer_enabled = false;
		this.issuer = null;
	}

	public void setMode(String m) {
		this.mode = m;
	}

	public String getMode() {
		return this.mode;
	}

	public Map<String, String> getModes() {
		return this.modes;
	}

	/**
	 *
	 */
	public void setModes(Map<String, String> m) {
		this.modes = m;
	}


	public void applyConfiguration() throws Exception {

	}

	/***********************************************************
	 *
	 * 				PRIVATE METHODS
	 *
	 ***********************************************************/

	/**
	 *
	 * @throws Exception
	 */
	private void init() throws Exception {
		this.createContentFolder();
		this.loadConfig();
		this.modes = new HashMap<String,String>();
		this.modes.put(BROADCASTER_MODE, BROADCASTER_MODE);
		this.modes.put(TICKER_MODE, TICKER_MODE);
		log.debug("----------------------------------------------------");
		log.debug("---- Bluetooth service configuration information: ");
		log.debug("-- Application folder: " + Constants.APP_FOLDER);
		log.debug("-- Content folder: " + Constants.CONTENT_FOLDER);
		log.debug("-- Config filename: " + Constants.CONFIG_FILE_LOCATION);
		log.debug("----------------------------------------------------");
	}

	private void loadConfig() throws Exception {
		Constants.CONFIG_FILE_LOCATION = Constants.APP_FOLDER +
		File.separator + Constants.CONFIG_FILE;
		log.debug(Constants.CONFIG_FILE_LOCATION);
		this.config_file = new File(Constants.CONFIG_FILE_LOCATION);
		if(!this.config_file.exists()) {
			this.copyConfigFile(this.config_file);
		}
		FileInputStream fis = new FileInputStream(this.config_file);
		Properties props = new Properties();
		props.load(fis);
		this.inquirerFrequency = Integer.parseInt(props.
				getProperty(Constants.CONFIG_PREFIX + "inquirerFrequency"));
		this.issuerFrequency = Integer.parseInt(props.
				getProperty(Constants.CONFIG_PREFIX + "issuerFrequency"));
		this.mode = props.getProperty(Constants.CONFIG_PREFIX + "mode");
	}

	private void copyConfigFile(File destination) throws Exception {
		FileOutputStream fos = new FileOutputStream(destination);
		ResourceFinder resource_finder = new ResourceFinder();
		String source_path = resource_finder.getResourceAsFileSystemPath("",
				Constants.CONFIG_FILE);
		File sourceFile = new File(source_path);
		byte[] content = FileUtils.extractFileContent(sourceFile);
		FileUtils.binaryTransferm(fos, content);
	}

	private void createContentFolder()
		throws Exception {
		Constants.APP_FOLDER = Constants.TEMP_FOLDER +
			File.separator + Constants.APP_FOLDER_NAME;
		File folder = new File(Constants.APP_FOLDER);
		if(!folder.exists()) {
			if(!folder.mkdir()) {
				throw new Exception("Imposible crear directorio de " +
						"aplicacion en la ruta " + folder.getAbsolutePath());
			}
		}
		Constants.CONTENT_FOLDER = Constants.APP_FOLDER + File.separator +
			Constants.CONTENT_FOLDER_NAME;
		folder = new File(Constants.CONTENT_FOLDER);
		if(!folder.exists()) {
			if(!folder.mkdir()) {
				throw new Exception("Imposible crear directorio de " +
						"contenidos en la ruta " + folder.getAbsolutePath());
			}
		}
		FileUtils.eraseFiles(Constants.CONTENT_FOLDER);
	}

}